//! 过滤器模块测试
//!
//! 测试 Level::should_log 过滤逻辑和边界条件

#![allow(clippy::assertions_on_constants, clippy::useless_vec)]

use log4r::Level;

// ============================================================================
// P0: 核心过滤逻辑测试
// ============================================================================

/// [P0] 测试 should_log 基本过滤逻辑
#[test]
fn test_should_log_basic_filtering() {
    // GIVEN: 过滤级别为 INFO
    let filter = Level::Info;

    // WHEN/THEN: 低于 INFO 的级别不应记录
    assert!(!Level::Trace.should_log(filter), "TRACE < INFO，不应记录");
    assert!(!Level::Debug.should_log(filter), "DEBUG < INFO，不应记录");

    // WHEN/THEN: INFO 及以上级别应记录
    assert!(Level::Info.should_log(filter), "INFO >= INFO，应记录");
    assert!(Level::Warn.should_log(filter), "WARN > INFO，应记录");
    assert!(Level::Error.should_log(filter), "ERROR > INFO，应记录");
    assert!(Level::Fatal.should_log(filter), "FATAL > INFO，应记录");
}

/// [P0] 测试 should_log 所有级别组合
#[test]
fn test_should_log_all_level_combinations() {
    // GIVEN: 所有日志级别
    let levels = [
        Level::Trace,
        Level::Debug,
        Level::Info,
        Level::Warn,
        Level::Error,
        Level::Fatal,
    ];

    // WHEN/THEN: 验证所有组合
    for (filter_idx, filter) in levels.iter().enumerate() {
        for (level_idx, level) in levels.iter().enumerate() {
            let should_log = level.should_log(*filter);
            let expected = level_idx >= filter_idx;
            assert_eq!(
                should_log, expected,
                "级别 {:?} 过滤 {:?}: 期望 {}, 实际 {}",
                level, filter, expected, should_log
            );
        }
    }
}

/// [P0] 测试 TRACE 过滤级别（记录所有）
#[test]
fn test_should_log_trace_filter_logs_all() {
    // GIVEN: 过滤级别为 TRACE（最低）
    let filter = Level::Trace;

    // WHEN/THEN: 所有级别都应记录
    assert!(Level::Trace.should_log(filter));
    assert!(Level::Debug.should_log(filter));
    assert!(Level::Info.should_log(filter));
    assert!(Level::Warn.should_log(filter));
    assert!(Level::Error.should_log(filter));
    assert!(Level::Fatal.should_log(filter));
}

/// [P0] 测试 FATAL 过滤级别（仅记录 FATAL）
#[test]
fn test_should_log_fatal_filter_logs_only_fatal() {
    // GIVEN: 过滤级别为 FATAL（最高）
    let filter = Level::Fatal;

    // WHEN/THEN: 只有 FATAL 应记录
    assert!(!Level::Trace.should_log(filter));
    assert!(!Level::Debug.should_log(filter));
    assert!(!Level::Info.should_log(filter));
    assert!(!Level::Warn.should_log(filter));
    assert!(!Level::Error.should_log(filter));
    assert!(Level::Fatal.should_log(filter));
}

// ============================================================================
// P1: 边界条件测试
// ============================================================================

/// [P1] 测试相同级别过滤
#[test]
fn test_should_log_same_level() {
    // GIVEN: 各种级别
    let levels = [
        Level::Trace,
        Level::Debug,
        Level::Info,
        Level::Warn,
        Level::Error,
        Level::Fatal,
    ];

    // WHEN/THEN: 相同级别应该记录
    for level in levels {
        assert!(level.should_log(level), "级别 {:?} 应该通过自身过滤", level);
    }
}

/// [P1] 测试 DEBUG 过滤级别
#[test]
fn test_should_log_debug_filter() {
    // GIVEN: 过滤级别为 DEBUG
    let filter = Level::Debug;

    // WHEN/THEN: TRACE 不记录，其他都记录
    assert!(!Level::Trace.should_log(filter));
    assert!(Level::Debug.should_log(filter));
    assert!(Level::Info.should_log(filter));
    assert!(Level::Warn.should_log(filter));
    assert!(Level::Error.should_log(filter));
    assert!(Level::Fatal.should_log(filter));
}

/// [P1] 测试 WARN 过滤级别
#[test]
fn test_should_log_warn_filter() {
    // GIVEN: 过滤级别为 WARN
    let filter = Level::Warn;

    // WHEN/THEN: TRACE/DEBUG/INFO 不记录
    assert!(!Level::Trace.should_log(filter));
    assert!(!Level::Debug.should_log(filter));
    assert!(!Level::Info.should_log(filter));
    assert!(Level::Warn.should_log(filter));
    assert!(Level::Error.should_log(filter));
    assert!(Level::Fatal.should_log(filter));
}

/// [P1] 测试 ERROR 过滤级别
#[test]
fn test_should_log_error_filter() {
    // GIVEN: 过滤级别为 ERROR
    let filter = Level::Error;

    // WHEN/THEN: 只有 ERROR 和 FATAL 记录
    assert!(!Level::Trace.should_log(filter));
    assert!(!Level::Debug.should_log(filter));
    assert!(!Level::Info.should_log(filter));
    assert!(!Level::Warn.should_log(filter));
    assert!(Level::Error.should_log(filter));
    assert!(Level::Fatal.should_log(filter));
}

// ============================================================================
// P2: 性能和内联测试
// ============================================================================

/// [P2] 测试 should_log 是 const fn（编译时验证）
#[test]
fn test_should_log_is_const() {
    // GIVEN: const 上下文
    const FILTER: Level = Level::Info;
    const SHOULD_LOG_TRACE: bool = Level::Trace.should_log(FILTER);
    const SHOULD_LOG_INFO: bool = Level::Info.should_log(FILTER);
    const SHOULD_LOG_FATAL: bool = Level::Fatal.should_log(FILTER);

    // WHEN/THEN: 编译时计算正确
    assert!(!SHOULD_LOG_TRACE);
    assert!(SHOULD_LOG_INFO);
    assert!(SHOULD_LOG_FATAL);
}

/// [P2] 测试 should_log 多次调用一致性
#[test]
fn test_should_log_consistency() {
    // GIVEN: 固定的级别和过滤器
    let level = Level::Info;
    let filter = Level::Debug;

    // WHEN: 多次调用
    let results: Vec<bool> = (0..100).map(|_| level.should_log(filter)).collect();

    // THEN: 结果应一致
    assert!(results.iter().all(|&r| r), "所有调用结果应一致为 true");
}

// ============================================================================
// 与 LogEvent 集成测试
// ============================================================================

/// [P1] 测试 LogEvent 级别过滤场景
#[test]
fn test_log_event_level_filtering_scenario() {
    use log4r::LogEvent;

    // GIVEN: 模拟日志系统过滤级别为 WARN
    let filter_level = Level::Warn;

    // WHEN: 创建各级别的日志事件
    let events = vec![
        LogEvent::new(Level::Trace, "app", "trace msg"),
        LogEvent::new(Level::Debug, "app", "debug msg"),
        LogEvent::new(Level::Info, "app", "info msg"),
        LogEvent::new(Level::Warn, "app", "warn msg"),
        LogEvent::new(Level::Error, "app", "error msg"),
        LogEvent::new(Level::Fatal, "app", "fatal msg"),
    ];

    // THEN: 过滤后只有 WARN 及以上级别
    let filtered: Vec<_> = events
        .iter()
        .filter(|e| e.level.should_log(filter_level))
        .collect();

    assert_eq!(filtered.len(), 3, "应有 3 个事件通过过滤");
    assert_eq!(filtered[0].level, Level::Warn);
    assert_eq!(filtered[1].level, Level::Error);
    assert_eq!(filtered[2].level, Level::Fatal);
}

/// [P1] 测试模块级别覆盖场景
#[test]
fn test_module_level_override_scenario() {
    // GIVEN: 全局级别 INFO，模块 "db" 级别 DEBUG
    let global_filter = Level::Info;
    let db_module_filter = Level::Debug;

    // WHEN: 检查 DEBUG 级别日志
    let debug_level = Level::Debug;

    // THEN: 全局过滤不通过，模块过滤通过
    assert!(
        !debug_level.should_log(global_filter),
        "DEBUG 不应通过全局 INFO 过滤"
    );
    assert!(
        debug_level.should_log(db_module_filter),
        "DEBUG 应通过模块 DEBUG 过滤"
    );
}
